package org.dingfugui.triple.protocol.mssage;

import org.dingfugui.triple.rpc.RequestMessage;
import org.dingfugui.triple.rpc.ResponseMessage;
import org.dingfugui.triple.serialize.Serialize;

/**
 * 请求报文格式
 * 报文头(4):报文长度(3)+类型(1)
 * 请求报文体(n):
 * service长度(3)+service(n)+method长度(3)+method(n)+types长度(3)+types(n)+params长度(3)+params(n)
 * <p>
 * 响应报文体(n):
 * result(n)
 * ###############@@@@@@@@@@@@@@@@@@!!!!!!!!!!!!!!!!!!!!
 * Created by fugui.ding on 2015/4/28.
 */
public class TripleMessageHandler extends AbstractDefaultTranslator {
    private Serialize serialize;

    public TripleMessageHandler(Serialize serialize) {
        this.serialize = serialize;
    }

    @Override
    byte[] buildMessageBody(RequestMessage request) {
        return new byte[0];
    }

    @Override
    byte[] buildMessageBody(ResponseMessage response) {
        return new byte[0];
    }

    @Override
    RequestMessage buildRequest(byte[] body) {
        return null;
    }

    @Override
    ResponseMessage buildResponse(byte[] body) {
        return null;
    }

    @Override
    public int getMessageHeadSize() {
        return 4;//todo：不仅要返回报文头长度，还应该返回报文头里哪一段表示报文长度。不如提供一个方法，返回报文长度。
    }


    @Override
    public byte[] encodeRequest(RequestMessage event) {


        return new byte[0];
    }

    @Override
    public RequestMessage decodeRequest(byte[] data) {
        byte[] serviceData = getData(data, getMessageHeadSize());
        byte[] methodData = getData(data, serviceData.length + 4);
        byte[] typesData = getData(data, methodData.length + 4);
        byte[] paramsData = getData(data, typesData.length + 4);

        String service = String.valueOf(serialize.deserialize(serviceData));
        String method = String.valueOf(serialize.deserialize(methodData));
        Class[] types = (Class[]) serialize.deserialize(serviceData);
        Object[] param = (Object[]) serialize.deserialize(paramsData);

        RequestMessage request = new RequestMessage(service, method, types, param);
        return request;
    }

    @Override
    public byte[] encodeResponse(ResponseMessage response) {
        byte[] resultData = serialize.serialize(response.getResult());

        int length = 4 + resultData.length;
        byte[] msg = new byte[length];

        msg[0] = (byte) (length & 0xF);
        msg[1] = (byte) (length >>> 8);
        msg[2] = (byte) (length >>> 16);

        System.arraycopy(resultData, 0, msg, 4, resultData.length);
        return msg;
    }

    @Override
    public ResponseMessage decodeResponse(byte[] data) {
        return null;
    }


    /**
     * 获取报文下一组数据内容
     *
     * @param data   报文数组
     * @param offset 从哪个坐标开始
     * @return
     */
    private byte[] getData(byte[] data, int offset) {

        int length = getLength(data, offset);

        byte[] target = new byte[length];

        System.arraycopy(data, offset, target, 0, length);
        return target;
    }

    /**
     * 获取报文下一组数据长度
     *
     * @param data
     * @param offset
     * @return
     */
    private int getLength(byte[] data, int offset) {
        byte b1 = data[offset];
        byte b2 = data[offset + 1];
        byte b3 = data[offset + 2];

        int length = (b1 & 0xF) | (b2 & 0xF << 8) | (b3 & 0xF << 16);
        return length;
    }


}
